﻿using System;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Diagnostics;
using System.Windows.Controls.Primitives;

namespace System.Windows.BidiControls
{
    [TemplatePart(Name="Root", Type=typeof(Panel)), TemplatePart(Name="MonthTemplate", Type=typeof(ControlTemplate))]
    public class Calendar : System.Windows.Controls.Calendar
    {
        private Panel rootObject = null;
        private Panel monthControlRoot = null;
        private Grid monthView = null;
        private Grid yearView = null;
        private bool isInitialized = false;
        private Controls.Button nextButton = null;
        private Controls.Button previousButton = null;
        private Controls.Button headerButton = null;
        readonly DispatcherTimer timer = new DispatcherTimer();

        public Calendar()
        {
            DefaultStyleKey = typeof(System.Windows.Controls.Calendar);
            this.Loaded += new RoutedEventHandler(ArabicCalendar_Loaded);
            this.SelectedDatesChanged += new EventHandler<SelectionChangedEventArgs>(ArabicCalendar_SelectedDatesChanged);
            this.DisplayModeChanged += new EventHandler<CalendarModeChangedEventArgs>(ArabicCalendar_DisplayModeChanged);
        }

        void ArabicCalendar_DisplayModeChanged(object sender, CalendarModeChangedEventArgs e)
        {
            timer.Start();
        }

        void ArabicCalendar_SelectedDatesChanged(object sender, SelectionChangedEventArgs e)
        {
            timer.Start();
        }

        void ArabicCalendar_Loaded(object sender, RoutedEventArgs e)
        {
            int childrenCount = VisualTreeHelper.GetChildrenCount(this);

            //foreach (FrameworkElement el in this.rootObject.Children)
            //{
            //    if (el is TextBlock)
            //        ((TextBlock)el).Text = NBidi.NBidi.LogicalToVisual(((TextBlock)el).Text);
            //}
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            var root = this.GetTemplateChild("Root");

            int childrenCount = VisualTreeHelper.GetChildrenCount(this);
            timer.Interval = new TimeSpan(10);
            timer.Tick += new EventHandler(timer_Tick);
            timer.Start();

            this.rootObject = VisualTreeHelper.GetChild(this, 0) as Panel;
        }

        void timer_Tick(object sender, EventArgs e)
        {
            foreach (FrameworkElement el in this.rootObject.Children)
            {
                int childrenCount = VisualTreeHelper.GetChildrenCount(el);
                if (childrenCount == 0)
                {
                    timer.Start();
                    return;
                }

                else
                {
                    timer.Stop();
                    if (!isInitialized)
                    {
                        monthControlRoot = VisualTreeHelper.GetChild(el, 0) as Panel;
                        Debug.Assert(monthControlRoot is Grid);
                        //Debug.Assert(((Grid)monthControlRoot).ColumnDefinitions.Count == 3);
                        //Debug.Assert(((Grid)monthControlRoot).RowDefinitions.Count == 2);

                        monthView = monthControlRoot.FindName("MonthView") as Grid;
                        Debug.Assert(monthView != null, "MonthView can not be found");
                        Debug.Assert(monthView.ColumnDefinitions.Count == 7);
                        Debug.Assert(monthView.RowDefinitions.Count == 7);

                        yearView = monthControlRoot.FindName("YearView") as Grid;
                        Debug.Assert(monthView != null, "MonthView can not be found");
                        //var dayButtons = from d in monthView.Children
                        //                 where d is DayButton
                        //                 select d;
                        //foreach(DayButton b in dayButtons)
                        //{
                        //    b.MouseLeftButtonUp += new MouseButtonEventHandler(DayButtonClick);
                        //}


                        headerButton = monthControlRoot.FindName("HeaderButton") as Controls.Button;
                        Debug.Assert(headerButton != null, "HeaderButton can not be found, make sure that in the control template you have the header button named HeaderButton");
                        //headerButton.SizeChanged += new SizeChangedEventHandler(headerButton_SizeChanged);

                        nextButton = monthControlRoot.FindName("PreviousButton") as Controls.Button;
                        Debug.Assert(nextButton != null, "NextButton can not be found, make sure that in the control template you have the next button named NextButton");
                        nextButton.Click += new RoutedEventHandler(PrevNextButton_Click);
                        previousButton = monthControlRoot.FindName("NextButton") as Controls.Button;
                        previousButton.Click += new RoutedEventHandler(PrevNextButton_Click);
                        Debug.Assert(previousButton != null, "PreviousButton can not be found, make sure that in the control template you have the previous button named PreviousButton");
                        isInitialized = true;
                    }
                    //headerButton.SizeChanged += new SizeChangedEventHandler(headerButton_SizeChanged);
                    if (headerButton.Content != null && headerButton.Content.ToString()[0] != ' ')
                    {
                        headerButton.Content = " " + NBidi.NBidi.LogicalToVisual(headerButton.Content.ToString());

                        if (this.DisplayMode == CalendarMode.Month)
                        {
                            for (int i = 0; i < 7; i++)
                            {
                                Controls.TextBlock block = monthView.Children[i] as Controls.TextBlock;
                                block.Text = NBidi.NBidi.LogicalToVisual(block.Text);
                            }
                        }
                    }
                    if (DisplayMode == CalendarMode.Year)
                    {
                        var monthButtons = from m in yearView.Children
                                           where m is CalendarButton
                                           select m;
                        foreach (CalendarButton monthButton in monthButtons)
                        {
                            if (monthButton.Content != null && monthButton.Content.ToString().Length > 0 && monthButton.ToString()[0] != ' ')
                            {
                                monthButton.Content = " " + NBidi.NBidi.LogicalToVisual(monthButton.Content.ToString());
                            }
                        }
                    }
                }
            }
        }

        /*
                void DayButtonClick(object sender, MouseButtonEventArgs e)
                {
                    timer.Start();
                }
        */

        /*
                void headerButton_SizeChanged(object sender, SizeChangedEventArgs e)
                {
                    if(headerButton.Content != null && headerButton.Content.ToString().Length > 0 && headerButton.Content.ToString()[0] != ' ')
                    {
                        headerButton.Content = NBidi.NBidi.LogicalToVisual(headerButton.Content.ToString());
                    }
                }
        */

        void PrevNextButton_Click(object sender, RoutedEventArgs e)
        {
            timer.Start();
        }
    }
}